Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transition to salsa coarse-grained tracked structs #15763

Merged
merged 6 commits into from
Feb 11, 2025

Conversation

ibraheemdev
Copy link
Member

@ibraheemdev ibraheemdev commented Jan 27, 2025

Summary

Transition to using coarse-grained tracked structs (depends on salsa-rs/salsa#657). For now, this PR doesn't add any #[tracked] fields, meaning that any changes cause the entire struct to be invalidated. It also changes AstNodeRef to be compared/hashed by pointer address, instead of performing a deep AST comparison.

Test Plan

This yields a 10-15% improvement on my machine (though weirdly some runs were 5-10% without being flagged as inconsistent by criterion, is there some non-determinism involved?). It's possible that some of this is unrelated, I'll try applying the patch to the current salsa version to make sure.

@ibraheemdev ibraheemdev added the performance Potential performance improvement label Jan 27, 2025
Copy link

codspeed-hq bot commented Jan 27, 2025

CodSpeed Performance Report

Merging #15763 will improve performances by 14.08%

Comparing ibraheemdev:salsa-coarse-deps (ba377f2) with main (7fbd89c)

Summary

⚡ 2 improvements
✅ 30 untouched benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
red_knot_check_file[cold] 95 ms 90.7 ms +4.73%
red_knot_check_file[incremental] 5.2 ms 4.5 ms +14.08%

@dhruvmanila dhruvmanila added the red-knot Multi-file analysis & type inference label Jan 27, 2025
Copy link
Contributor

github-actions bot commented Jan 27, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

@ibraheemdev

This comment was marked as resolved.

@ibraheemdev

This comment was marked as resolved.

@MichaReiser

This comment was marked as resolved.

@MichaReiser

This comment was marked as resolved.

@ibraheemdev

This comment was marked as resolved.

@MichaReiser

This comment was marked as resolved.

@MichaReiser

This comment was marked as outdated.

@MichaReiser MichaReiser added the do-not-merge Do not merge this pull request label Feb 9, 2025
@MichaReiser

This comment was marked as outdated.

@@ -42,7 +40,6 @@ pub(crate) struct PatternConstraint<'db> {
#[return_ref]
pub(crate) kind: PatternConstraintKind<'db>,

#[no_eq]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Countme's eq implementation is a no-op anyway

pub(crate) file_scope: FileScopeId,

#[no_eq]
#[return_ref]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expression is Copy, no need to return a ref

@MichaReiser

This comment was marked as outdated.

@MichaReiser

This comment was marked as outdated.

@MichaReiser
Copy link
Member

MichaReiser commented Feb 10, 2025

I updated the salsa dep to use the upstream commit and I'll mark it ready for review. It might be good to get a review from someone other than me, considering that I did some of the work but I think it's also fine if it's just me reviewing it if everyone else is short on time. I'll merge the PR on Wednesday if it hasn't received any reviews by then.

@MichaReiser MichaReiser removed the do-not-merge Do not merge this pull request label Feb 10, 2025
@MichaReiser MichaReiser marked this pull request as ready for review February 10, 2025 17:22
Copy link
Member

@AlexWaygood AlexWaygood Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm okay with removing this module for now per the conversation we had in #15834, but it seems unrelated to the PR?

Copy link
Member

@MichaReiser MichaReiser Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is related in the sense that the upgrade requires changes to that module and I decided that it's not worth my time updating unused code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is enough to make everything compile without warnings, FWIW :P

diff --git a/crates/red_knot_python_semantic/src/types/statistics.rs b/crates/red_knot_python_semantic/src/types/statistics.rs
index 625a38d52..561765dd3 100644
--- a/crates/red_knot_python_semantic/src/types/statistics.rs
+++ b/crates/red_knot_python_semantic/src/types/statistics.rs
@@ -1,11 +1,12 @@
+#![allow(unused)]
+
 use crate::types::{infer_scope_types, semantic_index, Type};
 use crate::Db;
 use ruff_db::files::File;
 use rustc_hash::FxHashMap;
 
 /// Get type-coverage statistics for a file.
-#[salsa::tracked(return_ref)]
-pub fn type_statistics<'db>(db: &'db dyn Db, file: File) -> TypeStatistics<'db> {
+pub(crate) fn type_statistics(db: &dyn Db, file: File) -> TypeStatistics {
     let _span = tracing::trace_span!("type_statistics", file=?file.path(db)).entered();
 
     tracing::debug!(
@@ -71,7 +72,7 @@ mod tests {
         db: &'db mut TestDb,
         filename: &str,
         source: &str,
-    ) -> &'db TypeStatistics<'db> {
+    ) -> TypeStatistics<'db> {
         db.write_dedented(filename, source).unwrap();

Copy link
Contributor

@carljm carljm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable to me!

fn eq(&self, other: &Self) -> bool {
self.node().eq(other.node())
self.node.eq(&other.node)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the relationship of this change to the rest of the PR?

Could we do this today in main, independently of the tracked-struct changes? And if we did, how much of the perf win of this PR would come with it?

(Not really suggesting we need to split it out, just trying to understand this change and its perf impact better.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could probably revert this change now that AstNodeRef fields are tracked again. Let me try tomorrow.

I don't think changing the implementation on main would lead to a performance improvement because all AstNodeRef fields are marked with no_eq and are never marked as id (they're never hashed). That means this implementation should be mostly unused today.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you decided not to revert this change? Anything worth documenting about why?

@MichaReiser MichaReiser merged commit 69d86d1 into astral-sh:main Feb 11, 2025
21 checks passed
MichaReiser added a commit that referenced this pull request Feb 11, 2025
…Eq` or `Hash` (#16100)

## Summary

This is a follow up to
#15763 (comment)

It reverts the change to using ptr equality for `AstNodeRef`s, which in
turn removes the `Eq`, `PartialEq`, and `Hash` implementations for
`AstNodeRef`s parametrized with AST nodes.
Cheap comparisons shouldn't be needed because the node field is
generally marked as `[#tracked]` and `#[no_eq]` and removing the
implementations even enforces that those
attributes are set on all `AstNodeRef` fields (which is good).

The only downside this has is that we technically wouldn't have to mark
the `Unpack::target` as `#[tracked]` because
the `target` field is accessed in every query accepting `Unpack` as an
argument.

Overall, enforcing the use of `#[tracked]` seems like a good trade off,
espacially considering that it's very likely that
we'd probably forget to mark the `Unpack::target` field as tracked if we
add a new `Unpack` query that doesn't access the target.

## Test Plan

`cargo test`
dcreager added a commit that referenced this pull request Feb 11, 2025
* main:
  add diagnostic `Span` (couples `File` and `TextRange`) (#16101)
  Remove `Hash` and `Eq` from `AstNodeRef` for types not implementing `Eq` or `Hash` (#16100)
  Fix release build warning about unused todo type message (#16102)
  [`pydocstyle`] Handle arguments with the same names as sections (`D417`) (#16011)
  [red-knot] Reduce usage of `From<Type>` implementations when working with `Symbol`s (#16076)
  Transition to salsa coarse-grained tracked structs (#15763)
  [`pyupgrade`] Handle micro version numbers correctly (`UP036`) (#16091)
  [red-knot] `T | object == object` (#16088)
  [`ruff`] Skip singleton starred expressions for `incorrectly-parenthesized-tuple-in-subscript` (`RUF031`) (#16083)
  Delete left-over `verbosity.rs (#16081)
  [red-knot] User-level configuration (#16021)
  Add `user_configuration_directory` to `System` (#16020)
@MichaReiser MichaReiser mentioned this pull request Feb 24, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Potential performance improvement red-knot Multi-file analysis & type inference
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants